package com.quant.strategy;

import com.quant.entity.StockDaily;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

/**
 * RSI策略
 * RSI低于超卖线时买入，高于超买线时卖出
 * @author lulj
 */
@Data
@Component
@Slf4j
public class RSIStrategy implements Strategy {
    private String name = "RSI策略";
    private int rsiPeriod = 6;  // RSI周期
    private double overbought = 70;  // 超买线
    private double oversold = 30;    // 超卖线
    private double positionRatio = 0.8;  // 仓位比例

	@Override
	public void init() {
		// 1. 参数有效性校验
		if (rsiPeriod <= 0) {
			throw new IllegalArgumentException("RSI周期必须为正数，当前值: " + rsiPeriod);
		}
		if (overbought <= 50 || overbought > 100) {
			throw new IllegalArgumentException("超买线必须在(50, 100]范围内，当前值: " + overbought);
		}
		if (oversold < 0 || oversold >= 50) {
			throw new IllegalArgumentException("超卖线必须在[0, 50)范围内，当前值: " + oversold);
		}
		if (oversold >= overbought) {
			throw new IllegalArgumentException("超卖线必须小于超买线，当前超卖: " + oversold + ", 超买: " + overbought);
		}
		if (positionRatio <= 0 || positionRatio > 1.0) {
			throw new IllegalArgumentException("仓位比例必须在(0, 1]范围内，当前值: " + positionRatio);
		}

		// 2. 检查支持的RSI周期（与getRSIValue方法中的支持列表对齐）
		Set<Integer> supportedPeriods = Set.of(6, 12, 24);
		if (!supportedPeriods.contains(rsiPeriod)) {
			throw new IllegalArgumentException("不支持的RSI周期: " + rsiPeriod + "，支持的周期为: " + supportedPeriods);
		}

		// 3. 初始化日志记录
		log.info("RSI策略初始化完成");
		log.info("策略参数 - RSI周期: {}天, 超买线: {}, 超卖线: {}, 仓位比例: {}%",
				rsiPeriod, overbought, oversold, positionRatio * 100);
	}

    @Override
    public int generateSignal(List<StockDaily> dailyList, int index) {
        // 确保有足够的数据计算RSI
        if (index < rsiPeriod) {
            return 0;
        }

        StockDaily current = dailyList.get(index);
        Double rsiValue = getRSIValue(current);

        if (rsiValue == null) {
            return 0;
        }

        // 超卖，买入信号
        if (rsiValue <= oversold) {
            return 1;
        }

        // 超买，卖出信号
        if (rsiValue >= overbought) {
            return -1;
        }

        return 0;
    }

    /**
     * 获取对应的RSI值
     */
    private Double getRSIValue(StockDaily daily) {
        switch (rsiPeriod) {
            case 6: return daily.getRsi6();
            case 12: return daily.getRsi12();
            case 24: return daily.getRsi24();
            default: throw new IllegalArgumentException("不支持的RSI周期: " + rsiPeriod);
        }
    }
}
